﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web.UI;

[assembly: WebResource("PTA.Res.Web.spaninvalid.jpg", "image/jpeg")]
[assembly: WebResource("PTA.Res.Web.textinvalid.gif", "image/gif")]
namespace PTA.Web
{
    public class ValidateBox : System.Web.UI.WebControls.TextBox
    {
        #region 客户端验证信息
        private static SpanInvalidStyle invalidspancss;
        private static TextInvalidStyle invalidtextcss;
        private const string validatejs = @"
        $(function ()
        {
            $('input.validatebutton').click(function ()
            {
                var me = $(this), valid = true, evt = { 'type': 'blur' }, msgs = [];
                me.parent(me.attr('validatepane') || document).find('input[validator]').each(function () { var x = CheckCtl($(this), evt); if (!x.valid) { valid = false; msgs.push(x.message); } });
                if (!valid) { alert(msgs.join('\n')); }
                return valid;
            });
            $('input[validator]').each(function () { $(this).bind('blur keyup change focus', function (evt) { CheckCtl($(this), evt); }).data('oriwidth', $(this).width()); });
            function CheckCtl(ctl, evt)
            {
                var validator = $.parseJSON(ctl.attr('validator'));
                var result = { 'valid': true, 'message': '', 'value': ctl.val(), 'target': validator.target, 'name': validator.name };
                if (validator['required'] && result.value.length == 0 && validator.required)
                {
                    result.message = result.name + '值不能为空！';
                    result.valid = false;
                }
                if (result.valid && validator['minlen'] && result.value.length < validator.minlen)
                {
                    result.message = result.name + '最小长度为' + validator.minlen + '！';
                    result.valid = false;
                }
                if (result.valid && validator['maxlen'] && result.value.length > validator.maxlen)
                {
                    result.message = result.name + '最大长度为' + validator.maxlen + '！';
                    result.valid = false;
                }
                if (result.valid && validator['minval'] && result.value < validator.minval)
                {
                    result.message = result.name + '最小值为' + validator.maxlen + '！';
                    result.valid = false;
                }
                if (result.valid && validator['maxval'] && result.value < validator.maxval)
                {
                    result.message = result.name + '最大值为' + validator.maxlen + '！';
                    result.valid = false;
                }
                if (result.valid && ValidatePatten[validator['pattern']])
                {
                    if (!(new RegExp(ValidatePatten[validator.pattern])).test(result.value))
                    {
                        result.message = result.name + '不合法' + '！';
                        result.valid = false;
                    }
                }
                if (result.valid)
                {
                    $(result.target).removeClass('invalid').removeAttr('title');
                    ctl.removeClass('invalid').attr('valuevalid', result.valid);
                }
                else
                {
                    ctl.addClass('invalid').attr('valuevalid', result.valid);
                    if (evt.type == 'blur')
                    {
                        ctl.width(ctl.data('oriwidth') - 16);
                        $(result.target).addClass('invalid').attr('title', result.message);
                    }
                    else
                    {
                        ctl.width(ctl.data('oriwidth'));
                        $(result.target).removeClass('invalid').attr('title', result.message);
                    }
                }
                return result;
            }
        });";
        private bool required = false;
        public bool Required
        {
            set
            {
                this.required = value;
            }
            get
            {
                return this.required;
            }
        }

        private int minLength = 0;
        public int MinLength
        {
            get
            {
                return this.minLength;
            }
            set
            {
                this.minLength = value;
            }
        }

        private int maxLength = 0;
        public override int MaxLength
        {
            get
            {
                return this.maxLength;
            }
            set
            {
                this.maxLength = value;
            }
        }

        private string minValue = string.Empty;
        public string MinValue
        {
            get
            {
                return this.minValue;
            }
            set
            {
                this.minValue = value;
            }
        }

        private string maxValue = string.Empty;
        public string MaxValue
        {
            get
            {
                return this.maxValue;
            }
            set
            {
                this.maxValue = value;
            }
        }

        private ValidateType pattern = ValidateType.None;
        public ValidateType Pattern
        {
            get
            {
                return this.pattern;
            }
            set
            {
                this.pattern = value;
            }
        }

        private string name = string.Empty;
        public string Name
        {
            get
            {
                return this.name ?? string.Empty;
            }
            set
            {
                this.name = value;
            }
        }
        #endregion

        protected override void CreateChildControls()
        {
            base.CreateChildControls();
            if (this.Page != null && !DesignMode)
            {
                if (invalidspancss == null)
                {
                    invalidspancss = new SpanInvalidStyle(Page.ClientScript.GetWebResourceUrl(typeof(ValidateBox), "PTA.Res.Web.spaninvalid.jpg"));
                }
                if (invalidtextcss == null)
                {
                    invalidtextcss = new TextInvalidStyle(Page.ClientScript.GetWebResourceUrl(typeof(ValidateBox), "PTA.Res.Web.textinvalid.gif"));
                }
            }
        }

        private string SerializeValidator()
        {
            System.Collections.Hashtable dt = new System.Collections.Hashtable();
            dt.Add("name", this.Name);
            dt.Add("required", required);
            if (minLength > 0)
            {
                dt.Add("minlen", minLength);
            }
            if (maxLength > 0)
            {
                dt.Add("maxlen", maxLength);
            }
            if (!string.IsNullOrEmpty(minValue))
            {
                dt.Add("minval", minValue);
            }
            if (!string.IsNullOrEmpty(maxValue))
            {
                dt.Add("maxval", maxValue);
            }
            dt.Add("pattern", pattern.ToString());
            dt.Add("target", "#" + ValidateLabelId); ;

            return dt.ToJson();
        }

        private string ValidateLabelId
        {
            get
            {
                return string.Format("{1}{0}{2}", this.ClientIDSeparator, this.ClientID, "ValidateCtl");
            }
        }

        protected override void OnPreRender(EventArgs e)
        {
            if (Page != null && Page.Header != null)
            {
                if (!Page.ClientScript.IsClientScriptBlockRegistered(typeof(ValidateBox), "VALIDATEBOX_JS"))
                {
                    Page.Header.StyleSheet.CreateStyleRule(invalidspancss, null, "span.invalid");
                    Page.Header.StyleSheet.CreateStyleRule(invalidtextcss, null, "input.invalid");
                    Page.ClientScript.RegisterClientScriptBlock(typeof(ValidateBox), "VALIDATEBOX_JS", validatejs, true);
                }
            }

            var validator = SerializeValidator();
            if (!string.IsNullOrEmpty(validator))
            {
                this.Attributes["validator"] = validator;
            }
            base.OnPreRender(e);
        }

        public override void RenderControl(HtmlTextWriter writer)
        {
            writer.AddStyleAttribute(HtmlTextWriterStyle.Display, "inline-block");
            writer.AddAttribute(HtmlTextWriterAttribute.Cellpadding, "0");
            writer.AddAttribute(HtmlTextWriterAttribute.Cellspacing, "0");
            writer.AddAttribute(HtmlTextWriterAttribute.Border, "0px");
            writer.RenderBeginTag(HtmlTextWriterTag.Table);
            writer.RenderBeginTag(HtmlTextWriterTag.Tr);
            writer.RenderBeginTag(HtmlTextWriterTag.Td);
            base.RenderControl(writer);
            writer.RenderEndTag();
            writer.RenderBeginTag(HtmlTextWriterTag.Td);
            if (this.Attributes["validator"] != null)
            {
                writer.AddStyleAttribute(HtmlTextWriterStyle.Display, "none");
                writer.AddAttribute(HtmlTextWriterAttribute.Id, ValidateLabelId);
                writer.RenderBeginTag(HtmlTextWriterTag.Span);
                writer.Write("　");
                writer.RenderEndTag();
            }
            writer.RenderEndTag();
            writer.RenderEndTag();
            writer.RenderEndTag();
        }

        internal class SpanInvalidStyle : System.Web.UI.WebControls.Style
        {
            private string picurl = string.Empty;
            internal SpanInvalidStyle(string picurl)
            {
                this.picurl = picurl;
            }
            protected override void FillStyleAttributes(CssStyleCollection attributes, IUrlResolutionService urlResolver)
            {
                base.FillStyleAttributes(attributes, urlResolver);
                attributes.Add(HtmlTextWriterStyle.Display, "inline-block !important");
                attributes.Add(HtmlTextWriterStyle.Height, "16px");
                attributes.Add(HtmlTextWriterStyle.Width, "16px");
                attributes.Add(HtmlTextWriterStyle.BackgroundImage, string.Format("url({0})", picurl));
                attributes.Add(HtmlTextWriterStyle.Cursor, "pointer");
            }
        }

        internal class TextInvalidStyle : System.Web.UI.WebControls.Style
        {
            private string picurl = string.Empty;
            internal TextInvalidStyle(string picurl)
            {
                this.picurl = picurl;
            }
            protected override void FillStyleAttributes(CssStyleCollection attributes, IUrlResolutionService urlResolver)
            {
                base.FillStyleAttributes(attributes, urlResolver);
                attributes.Add(HtmlTextWriterStyle.BackgroundColor, "lightyellow");
                attributes.Add(HtmlTextWriterStyle.BackgroundImage, string.Format("url({0})", picurl));
                attributes.Add(HtmlTextWriterStyle.BorderColor, "red");
                attributes.Add(HtmlTextWriterStyle.BorderStyle, "solid");
                attributes.Add(HtmlTextWriterStyle.BorderWidth, "1px");
                attributes.Add("background-repeat", "repeat-x");
                attributes.Add("background-position", "bottom");
            }
        }
    }

}
